const express = require('express')
const path = require('path');
const axios = require('axios');
const fs = require('fs')

const bodyParser = require('body-parser');
let jsonParser = bodyParser.json({ limit: '1mb' })
let urlencodedParser = bodyParser.urlencoded({ extended: false })

const {
  createServer
} = require('http');

const mdns = require('./router/mdns')
const wifiRouter = require('./router/wifi')
const uploadRouter = require('./router/upload')
const fileRouter = require('./router/file-reader')
// const rosRouter = require('./router/ros')
// const variableRouter = require('./router/variable')
console.log(0)
const scratchRouter = require('./router/scratch-cloud')
console.log(1)
//const bluetoothRouter = require('./router/bluetooth')
console.log(3)
const {
  systemRouter,
} = require('./router/system')
// const {
//   collaborationSheetRouter,
//   createSocketServer
// } = require('./router/collaboration-sheet')
console.log(2)
let config
try {
  config = require('./config.json')
} catch (error) {
  config = {
    "env": {
      "lang": "zh"
    }
  }
}
console.log(config)

// const data_dir = require('./router/scratch-runner/index').getProgramDir()
const exec = require('child_process').exec;
/*
const wss = new WebSocket.Server({
  server
});
wss.on('connection', function connection(ws, req) {
  const ip = req.connection.remoteAddress;
  debuglog('client with ip %s connected.', ip)
  ws.on('close', function() {
    debuglog('client with ip %s disconnected.', ip)
  });

  ws.on('message', function incoming(data) {
    debuglog(data);
    if (!(data && data.type)) {
      ws.send(JSON.stringify(Ret.Fail("data type invalid")))
      return
    }
  });
});
*/
const app = express()
// app.use('/scratch-runner', express.static(path.join(__dirname, 'scratch-runner')));
// app.use('/wifi', express.static(__dirname + '/wifi'));
app.use('/', (req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS")
  res.header("Access-Control-Allow-Headers", "Content-Type, x-token");
  if (req.method === "OPTIONS") {
    return res.status(200).end();
  } else {
    next()

  }
})

app.get('/test', (req, res) => {
  res.send('ok');
})



app.use('/static', express.static(path.join(__dirname, 'router/static')))
app.use('/wifi', wifiRouter)
// app.use('/collaborationSheet', collaborationSheetRouter)
/*
try {
  const serialRouter = require('./router/serial')
  app.use('/serial', jsonParser, urlencodedParser)
  app.use('/serial', serialRouter)
} catch (error) {
  console.log(error)
}
*/
// app.use('/bluetooth', bluetoothRouter)
app.use('/upload', uploadRouter)
app.use('/explore', fileRouter)
app.use('/explore', express.static(fileRouter.homedir))
// app.use('/rosNode', rosRouter)
// app.use('/variable', variableRouter)
app.use('/system', systemRouter)
app.use('/scratch', jsonParser)
app.use('/scratch', scratchRouter)
app.get('/stream_list', (req, res) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Content-Type");
  axios.get('http://localhost:8080/').then(result => {
    // console.log(result)
    // console.log(result.data)
    if (result && result.data) {
      res.send(result.data)
    } else {
      res.send('error')
    }
  })
})
app.use('/proxy', jsonParser)

app.get('/proxy', (req, res) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Content-Type");
  if (req.query.method == 'POST') {
    axios.post(req.query.url).then(result => {
      // console.log(result)
      // console.log(result.data)
      if (result && result.data) {
        res.send(result.data)
      } else {
        res.send('error')
      }
    }).catch(error => {
      console.log('error', error)
      res.send('error')
    })
  } else {
    axios.get(req.query.url).then(result => {
      // console.log(result)
      // console.log(result.data)
      if (result && result.data) {
        res.send(result.data)
      } else {
        res.send('error')
      }
    }).catch(error => {
      console.log('error', error)
      res.send('error')
    })
  }
})

app.post('/proxy', (req, res) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Content-Type");
  if (req.query.method == 'POST') {
    console.log(req.body)
    axios.post(req.query.url, req.body).then(result => {
      // console.log(result)
      // console.log(result.data)
      if (result && result.data) {
        res.send(result.data)
      } else {
        res.send('error')
      }
    }).catch(error => {
      console.log('error', error)
      res.send('error')
    })
  } else {
    axios.get(req.query.url, { params: req.body }).then(result => {
      // console.log(result)
      // console.log(result.data)
      if (result && result.data) {
        res.send(result.data)
      } else {
        res.send('error')
      }
    }).catch(error => {
      console.log('error', error)
      res.send('error')
    })
  }
})


app.use('/app', express.static(path.join(__dirname, '../app')));
app.get('/app', (req, res) => {
  var data = fs.readFileSync(path.join(__dirname, '../app/index.html'), {
    encoding: 'utf8'
  });
  res.send(data);
})

mainWindow = null


app.get('/focus', (req, res) => {
  res.send('ok');
  console.log('show mainWindow')
  // mainWindow.focused = true
  // mainWindow.show()
  if (mainWindow) {
    mainWindow.focus()
  }
})

const server = createServer(app)
// createSocketServer(server)
try {
  const electron = require('electron')
  const BrowserWindow = electron.BrowserWindow
  const globalShortcut = electron.globalShortcut
  function createWindow() {

    /*
    globalShortcut.register('ESC', () => {
      mainWindow.setFullScreen(false);
    })
    */

    mainWindow = new BrowserWindow({
      width: 240,
      height: 320,
      // autoHideMenuBar: true, //remove menubar but save minimize maxmize controls
      frame: false, //remove menubar and control
      webPreferences: {
        nodeIntegration: false
      }
    })

    mainWindow.on('blur', () => {
      console.log('mainWindow blured')
      mainWindow.focused = false
    })

    mainWindow.on('focus', () => {
      console.log('mainWindow focused')
      mainWindow.focused = true
    })
    mainWindow.on('show', () => {
      console.log('mainWindow showed')
    })

    let win = mainWindow
    console.log(process.versions.electron)
    if (parseInt(process.versions.electron) >= 20) {
      win.webContents.session.on('select-hid-device', (event, details, callback) => {
        // Add events to handle devices being added or removed before the callback on
        // `select-hid-device` is called.
        win.webContents.session.on('hid-device-added', (event, device) => {
          console.log('hid-device-added FIRED WITH', device)
          // Optionally update details.deviceList
        })

        win.webContents.session.on('hid-device-removed', (event, device) => {
          console.log('hid-device-removed FIRED WITH', device)
          // Optionally update details.deviceList
        })

        event.preventDefault()
        if (details.deviceList && details.deviceList.length > 0) {
          callback(details.deviceList[0].deviceId)
        }
      })

      win.webContents.session.on('select-serial-port', (event, portList, webContents, callback) => {
        // Add listeners to handle ports being added or removed before the callback for `select-serial-port`
        // is called.
        win.webContents.session.on('serial-port-added', (event, port) => {
          console.log('serial-port-added FIRED WITH', port)
          // Optionally update portList to add the new port
        })

        win.webContents.session.on('serial-port-removed', (event, port) => {
          console.log('serial-port-removed FIRED WITH', port)
          // Optionally update portList to remove the port
        })
        console.log(portList)
        // let sensors = portList.filter(port => port.displayName == 'Espressif CDC Device' || port.displayName == 'USB JTAG/serial debug unit')
        event.preventDefault()
        if (portList && portList.length > 0) {
          let vendorId = ['6790']
          let arduino = portList.filter(p => p.vendorId && vendorId.indexOf(p.vendorId) >= 0)
          console.log(arduino)
          if (arduino.length > 0) {
            callback(arduino[0].portId)
          } else {
            callback(portList[portList.length - 1].portId)
          }
        } else {
          // eslint-disable-next-line n/no-callback-literal
          callback('') // Could not find any matching devices
        }
      })

      win.webContents.session.setPermissionRequestHandler((webContents, permission, callback, details) => {
        console.log(permission, details, 1)
        if ((permission === 'serial' || permission === 'media') && (details.securityOrigin.startsWith('http://localhost') || details.securityOrigin.startsWith('http://127.0.0.1') || details.securityOrigin === 'file:///')) {
          return callback(true)
        }
        return callback(false);
      })

      win.webContents.session.setDevicePermissionHandler((details) => {
        console.log(details, 2)
        if ((details.deviceType === 'serial' || details.deviceType === 'audio') && (details.origin.startsWith('http://localhost') || details.origin.startsWith('http://127.0.0.1') || details.origin === 'file:///')) {
          return true
        }

        return false
      })
    }



    mainWindow.loadURL("http://localhost:8000/app#!/" + `?lang=${config.env.lang}`)
    // mainWindow.loadURL('http://localhost:8000/app/static/learning-machine/audio.html')
    //mainWindow.loadURL('http://localhost:3000')
    mainWindow.setFullScreen(true);
    console.log(mainWindow)
  }
  electron.app.commandLine.appendSwitch("--disable-http-cache");
  electron.app.on('ready', () => {
    server.listen(8000, () => {
      console.log('Listening on http://localhost:8000 with electron');
      createWindow()
    })
  })
  mdns.start_mdns_server()
}
catch (error) {
  console.log(error)
  server.listen(8000, () => {
    console.log('Listening on http://localhost:8000');
    /*
        chromium-browser http://localhost:8000/app --window-size=240,320 \
        --kiosk \
        --noerrdialogs \
        --disable-session-crashed-bubble \
        --disable-infobars \
        --check-for-update-interval=604800 \
        --disable-pinch
    */
    /*
     exec('chromium-browser --app=http://localhost:8000/app --window-size=240,320 --window-position=0,0 --kiosk --noerrdialogs' +
       ' --disable-session-crashed-bubble --disable-infobars --check-for-update-interval=604800 --disable-pinch', (err, stdout, stderr) => {
         console.log(err, stdout, stderr)
       })
       */
  })
}
